# 指定 cmake 最小版本, 意指 cmake 版本小于指定版本则构建过程终止
cmake_minimum_required(VERSION 3.26)

# 语言环境配置 ###########################################################################################################

# 语言版本
set(CMAKE_CXX_STANDARD 14)

# 如果指定的语言版本不受支持, 则构建过程终止
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 只弃用 ISO C++ 标准的编译器标志, 而不使用特定编译器的扩展
set(CMAKE_CXX_EXTENSIONS OFF)

# 将 install_rpath 的设置应用在 build_rpath 上
# 避免在开发期间出现动态库找不到的问题
set(CMAKE_BUILD_WITH_INSTALL_RPATH True)

# 项目配置 ##############################################################################################################

# 项目名称和语言
project(graver LANGUAGES CXX VERSION 1.0.0)

# 发布目录
set(dist_dir ${CMAKE_BINARY_DIR}/dist)

# 二进制文件目录
set(bin_dir ${dist_dir}/bin)

# 启动文件目录
set(sbin_dir ${dist_dir}/sbin)

# 库文件目录
set(lib_dir ${dist_dir}/lib)

# 日志目录
set(log_dir ${dist_dir}/logs)

# 配置文件目录
set(conf_dir ${dist_dir}/conf)

# 内部库
# person 库
set(lib_person_name person)

# 工具类库
set(lib_util_name util)

# 配置类库
set(lib_configuration_name configuration)

find_package(PkgConfig REQUIRED)

# vcpkg find package ###################################################################################################
# fmt 库
find_package(fmt CONFIG REQUIRED)
get_target_property(fmt_LOCATION fmt::fmt LOCATION)
get_filename_component(fmt_DIRECTORY ${fmt_LOCATION} DIRECTORY)

if(CMAKE_BUILD_TYPE STREQUAL "Release")
    string(REPLACE "debug/" "" fmt_DIRECTORY ${fmt_DIRECTORY})
endif()

message(STATUS "fmt_DIRECTORY:${fmt_DIRECTORY}")

# spdlog 库
find_package(spdlog CONFIG REQUIRED)
get_target_property(spdlog_LOCATION spdlog::spdlog LOCATION)
get_filename_component(spdlog_DIRECTORY ${spdlog_LOCATION} DIRECTORY)

if(CMAKE_BUILD_TYPE STREQUAL "Release")
    string(REPLACE "debug/" "" spdlog_DIRECTORY ${spdlog_DIRECTORY})
endif()

message(STATUS "spdlog_DIRECTORY:${spdlog_DIRECTORY}")

# gmpxx
pkg_check_modules(gmpxx REQUIRED IMPORTED_TARGET gmpxx)

# 编译相关配置 ###########################################################################################################

# 测试覆盖率选项
option(ENABLE_COVERAGE "gen coverage" OFF)

if(ENABLE_COVERAGE)
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
endif()

message(STATUS "ENABLE_COVERAGE:${ENABLE_COVERAGE}")

# 生成 compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# 包含全局头文件
include_directories(${PROJECT_SOURCE_DIR}/include)

# 项目配置文件
configure_file(graver_configuration.h.in ${PROJECT_SOURCE_DIR}/include/graver/configuration/configuration.h)

# 添加子目录
add_subdirectory(src)

# 伪目标配置 ############################################################################################################

# 运行程序的伪目标
# cmake -S . -B build && cmake --build build && cmake --build build --target run
add_custom_target(run
    COMMAND ${bin_dir}/${PROJECT_NAME} # 执行的命令
    WORKING_DIRECTORY ${bin_dir} # 命令的工作目录
    COMMENT "run application" # 描述
    VERBATIM # 执行命令时不会对其进行任何转义或处理，而是直接按照命令中的内容执行
)

# 启用测试 ##############################################################################################################
enable_testing()
add_subdirectory(test)
